feat(tbor): implement HKDF and single-step (X9.63 / SP 800-56A) KDF derivation - #589
Merged
Conversation
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 19, 2026 03:36
ef86362 to
f3eaaf9
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 19, 2026 03:41
9fbaf2e to
a53b87a
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 20, 2026 19:27
f3eaaf9 to
46b9a59
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 20, 2026 19:28
a53b87a to
f7e8fd7
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 20, 2026 19:36
46b9a59 to
b6570db
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 20, 2026 19:36
f7e8fd7 to
cc24643
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 20, 2026 19:56
b6570db to
2e8344f
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 20, 2026 19:56
cc24643 to
89abf19
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 29, 2026 20:29
2e8344f to
9ac2c4f
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 29, 2026 20:32
89abf19 to
1099b80
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 29, 2026 20:52
9ac2c4f to
71a1bba
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 29, 2026 20:53
1099b80 to
cca55c9
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 29, 2026 22:05
71a1bba to
fe7bd92
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 29, 2026 22:05
cca55c9 to
fe95df8
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 29, 2026 22:19
fe7bd92 to
c80e592
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 29, 2026 22:19
fe95df8 to
7fabfd6
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 30, 2026 01:21
c80e592 to
d56870e
Compare
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 30, 2026 01:21
7fabfd6 to
6a35c73
Compare
Add three stateless masked-key TBOR crypto commands mirroring the MBOR vault-key-handle equivalents: - EccGenerateKey (0x17): generate an ECC keypair (P-256/384/521) and return the private key AEAD-GCM-256 masked under the requested scope plus the wire public key. Nothing is persisted on-device. - EccSign (0x18): unmask a caller-held masked ECC private key in place, ECDSA-sign a host-supplied pre-hashed digest, return raw r||s. - EcdhDerive (0x19): unmask a masked local ECC private key in place, derive an ECDH shared secret against a host peer public key, and re-mask the secret under a target scope. Uses the zero-copy reserve+fill encoder and in-place unmask (decode_mut) patterns. Recovered plaintext keys and derived secrets are scrubbed on every return path (scope exit only resets the bump watermark). ECC import is provided by the existing UnwrapKey (Ecc class); a cross-command test covers UnwrapKey-Ecc -> EccSign. Shared curve/kind mappings added to tbor from_pal (ecc_private, ecdh_secret, ecc_private_curve); dispatch/classifier wiring in mod.rs and op.rs. Wire schemas (fw + host mirror), emu integration tests (host- verified ECDSA roundtrip for all curves), and per-command docs included. Also harden the pre-existing RSA OAEP test decrypt_rejects_corrupted_oaep_ciphertext: corrupting the most-significant ciphertext byte can push the integer past the modulus, which OpenSSL reports as INTERNAL_ERROR but CNG (Windows) reports as DDI_CMD_FAILURE. Accept either rejection code so the platform-flaky test passes on Windows CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0b09e50a-a9be-4bae-b347-d42dc775a258
Vishal Soni (vsonims)
force-pushed
the
tbor/ecc-crypto
branch
from
July 30, 2026 01:35
d56870e to
97c3a91
Compare
…erivation Add two in-session TBOR KDF commands that derive key material from a caller-held masked ECDH shared secret (from EcdhDerive) and return the derived key masked under the requested scope — the KDF analogues of the ECC crypto commands, re-masking the output instead of vaulting it: - HkdfDerive (0x1C): HKDF (RFC 5869) with optional salt + info. - ConcatKdfDerive (0x1D): single-step "concatenation" KDF, selecting ANSI X9.63 (SEC 1 §3.6.1) or NIST SP 800-56A r3 one-step (§5.8.2.1) via a kdf_alg discriminant; both take a single info octet string. Both handlers unmask the ECDH secret in place, verify it is an ECDH shared-secret kind carrying `derive`, run the KDF into scratch, mask the output (AES / fixed- or variable-length HMAC) under the target scope, and scrub the recovered secret and derived scratch on every path. The shared KdfKeyType output-type enum moves to key_props (used by both commands). Single-step KDF primitive (azihsm_crypto): the X9.63 and SP 800-56A concatenation KDFs are implemented once, generically, over the shared Hasher — they need nothing but a hash, so a single platform-agnostic ConcatKdfAlgo serves both the OpenSSL (Linux) and CNG (Windows) backends (unlike HKDF, which is per-backend). Known-answer tests validate both variants against independently computed vectors (SHA-256/384/512, single- and multi-block, absent info). The std PAL x963_kdf / sp800_56a_kdf hooks (previously todo!() stubs) now delegate to it via a new StdKdf::concat_kdf; the Uno PAL already implemented them. Adds HsmError::ConcatKdfError and three CryptoError variants. Wire schemas (fw + host mirror), dispatch / classifier / op.rs wiring (in-session, session-id cross-checked, default-PSK gated) for both opcodes. Emu tests cover every output key type under each KDF (and each X9.63 / SP 800-56A variant), all hashes and scopes, optional salt/info, and rejection of unknown hash / KDF variant / key type, variable-length HMAC without / out-of-range length, and a non-ECDH-secret IKM. Per-command docs added. Based on tbor/ecc-crypto for the ECDH shared-secret input (EcdhDerive); uses opcodes 0x1C / 0x1D after the sibling AES / ECC / RSA / Hash crypto branches (0x15..0x1B). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0b09e50a-a9be-4bae-b347-d42dc775a258
Vishal Soni (vsonims)
force-pushed
the
tbor/kdf-crypto
branch
from
July 30, 2026 01:41
6a35c73 to
17f5477
Compare
Jayant Gandhi (jaygmsft)
previously approved these changes
Aug 1, 2026
Jayant Gandhi (jaygmsft)
dismissed
their stale review
August 3, 2026 23:28
The base branch was changed.
Jayant Gandhi (jaygmsft)
enabled auto-merge
August 3, 2026 23:30
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: af077e4d-51d9-45f3-8e20-ea7f68813d17
Jayant Gandhi (jaygmsft)
force-pushed
the
tbor/kdf-crypto
branch
from
August 3, 2026 23:42
dd1dfdb to
60a5336
Compare
Rajesh Gali (rajesh-gali)
approved these changes
Aug 4, 2026
Contributor
|
Copilot merge latest main |
Co-authored-by: jaygmsft <22506014+jaygmsft@users.noreply.github.com>
Contributor
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds two new in-session TBOR KDF derivation commands (HkdfDerive and ConcatKdfDerive) that take a caller-held masked ECDH shared secret, derive symmetric key material (AES/HMAC), and return the result masked under a requested scope. It also introduces a cross-platform single-step concatenation KDF implementation in azihsm_crypto and wires the std PAL’s previously-stubbed X9.63 / SP 800-56A hooks to that implementation, with end-to-end emu coverage and command documentation.
Changes:
- Implement
ConcatKdfAlgo(+ mode selection) inazihsm_cryptowith known-answer tests. - Add TBOR firmware handlers, wire schemas, dispatch/classifiers, and host-side wrappers for
HkdfDerive(0x1C) andConcatKdfDerive(0x1D). - Wire std PAL X9.63 / SP 800-56A KDF hooks and add emu integration tests + docs for both commands.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| rust-toolchain.toml | Adds rust-analyzer as a toolchain component. |
| fw/plat/std/pal/src/kdf.rs | Wires std PAL x963_kdf / sp800_56a_kdf to the std KDF driver’s concat KDF implementation. |
| fw/plat/std/pal/src/drivers/kdf.rs | Adds async StdKdf::concat_kdf using azihsm_crypto’s ConcatKdfAlgo. |
| fw/pal/traits/src/error.rs | Introduces HsmError::ConcatKdfError for concat-KDF failures. |
| fw/core/lib/src/op.rs | Marks opcodes 0x1C / 0x1D as InSession for session-flag validation. |
| fw/core/lib/src/ddi/tbor/mod.rs | Adds opcodes, dispatch routing, and opcode classifiers for the new TBOR KDF commands. |
| fw/core/lib/src/ddi/tbor/hkdf_derive.rs | Implements firmware TBOR HkdfDerive handler (unmask-in-place, derive, re-mask, scrub). |
| fw/core/lib/src/ddi/tbor/concat_kdf_derive.rs | Implements firmware TBOR ConcatKdfDerive handler (X9.63 / SP 800-56A, re-mask, scrub). |
| fw/core/ddi/tbor/types/src/lib.rs | Registers and re-exports the new TBOR KDF wire-schema modules. |
| fw/core/ddi/tbor/types/src/key_props.rs | Adds shared KdfKeyType open-enum for KDF output type selection. |
| fw/core/ddi/tbor/types/src/hkdf_derive.rs | Adds TBOR wire schema + round-trip tests for HkdfDerive (fw-side). |
| fw/core/ddi/tbor/types/src/concat_kdf_derive.rs | Adds TBOR wire schema + round-trip tests for ConcatKdfDerive (fw-side). |
| docs/tbor-ddi/README.md | Documents new opcodes in the TBOR DDI command table. |
| docs/tbor-ddi/commands/hkdf_derive.md | Adds command documentation for HkdfDerive. |
| docs/tbor-ddi/commands/concat_kdf_derive.md | Adds command documentation for ConcatKdfDerive. |
| ddi/tbor/types/tests/commands/mod.rs | Registers new emu integration test modules. |
| ddi/tbor/types/tests/commands/hkdf_derive.rs | Adds emu integration tests for HKDF derivation wiring, variants, scopes, and rejects. |
| ddi/tbor/types/tests/commands/concat_kdf_derive.rs | Adds emu integration tests for concat-KDF derivation wiring, variants, scopes, and rejects. |
| ddi/tbor/types/src/lib.rs | Registers and re-exports new host-side TBOR wrappers. |
| ddi/tbor/types/src/hkdf_derive.rs | Adds host-side request/response wrapper + basic encoding test for HkdfDerive. |
| ddi/tbor/types/src/concat_kdf_derive.rs | Adds host-side request/response wrapper + basic encoding test for ConcatKdfDerive. |
| crates/crypto/src/lib.rs | Adds CryptoError variants for concat-KDF failures. |
| crates/crypto/src/kdf/tests/mod.rs | Registers concat-KDF KAT module. |
| crates/crypto/src/kdf/tests/concat_tests.rs | Adds known-answer tests validating X9.63/SP 800-56A ordering, counters, truncation, and rejects. |
| crates/crypto/src/kdf/mod.rs | Wires ConcatKdfAlgo + re-exports ConcatKdfMode. |
| crates/crypto/src/kdf/concat.rs | Implements platform-agnostic X9.63 / SP 800-56A one-step concatenation KDF. |
Jayant Gandhi (jaygmsft)
approved these changes
Aug 4, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Aug 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds two in-session TBOR KDF commands that derive key material from a caller-held masked ECDH shared secret (from
EcdhDerive0x19) and return the derived key masked under the requested scope — the KDF analogues of the ECC crypto commands, re-masking the output instead of vaulting it.0x1CHkdfDerive0x1DConcatKdfDerivekdf_alg), single infoBoth derive AES (128/192/256) or HMAC (fixed SHA-256/384/512, or variable-length) keys.
Design
derive, run through the KDF into scratch, and the output masked under the target scope. The recovered secret and derived scratch are scrubbed on every path.KdfKeyTypeoutput-type enum lives inkey_props(used by both commands).azihsm_crypto: X9.63 and SP 800-56A are Hash-only, so one genericConcatKdfAlgoover the sharedHasherserves both OpenSSL (Linux) and CNG (Windows) — no per-backend code. The std PALx963_kdf/sp800_56a_kdfhooks (previouslytodo!()stubs) now delegate to it viaStdKdf::concat_kdf; the Uno PAL already implemented them.Changes
azihsm_crypto:ConcatKdfAlgo+ConcatKdfMode {X963, Sp800_56a}(crates/crypto/src/kdf/concat.rs), 3CryptoErrorvariants, known-answer tests (kdf/tests/concat_tests.rs).StdKdf::concat_kdf+ wired both PAL methods;HsmError::ConcatKdfError.op.rsfor0x1C/0x1D.hkdf_derive.md,concat_kdf_derive.md, README rows.Testing
azihsm_crypto: 501 lib tests pass (incl. X9.63 / SP 800-56A KATs vs. independently computed vectors).cargo checkfw core (host + Uno no_std) + Uno PAL ✅ · clippy (crypto / std-PAL / fw / host) ✅ · nightly fmt ✅ · copyright ✅.Notes
tbor/ecc-crypto) for the ECDH shared-secret input. Uses opcodes0x1C/0x1Dafter the sibling AES / ECC / RSA / Hash crypto branches (0x15..0x1B).ConcatKdfDeriveis TBOR-only (no MBOR analogue). The concat KDFs' byte-level correctness is proven by theazihsm_cryptoKATs; the emu tests verify command plumbing (the derived key is only observable masked).Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com